/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.server.index;

import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.server.GameServer;
import com.icee.myth.server.actor.Human;
import com.icee.myth.server.hegemony.HegemonyTarget;
import java.util.ArrayList;
import java.util.NavigableSet;
import java.util.TreeSet;

/**
 *
 * @author liuxianke
 */
public class PlayerIdsOfRank {
    private final TreeSet<Integer> playerIds = new TreeSet<Integer>();

    // lastSearchPlayerId记录上次查询助战玩家到达的id。每次查询列表时，都从lastSearchPlayerId开始向后查询playerIds表，若查到表末则循环从表头开始找，
    // 但每次查询最多从lastSearchPlayerId+1到表末，再从表头到lastSearchPlayerId
    public int lastSearchPlayerId;

    public PlayerIdsOfRank() {
    }

    public void add(int playerId) {
        if (!playerIds.add(playerId)) {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "Player[" + playerId + "] multi-add in same rank set."));
        }
    }

    public void remove(int playerId) {
        if (!playerIds.remove(playerId)) {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "Player[" + playerId + "] not in rank set when remove from it."));
        }
    }

    public int count() {
        return playerIds.size();
    }

    /**
     * 为human选取下一个玩家目标，若目标已经被选过则返回false
     * @param human
     * @param resultTargets
     * @return true:选择了目标 false:未选择目标
     */
    public boolean getHegemonyTarget(Human human, ArrayList<HegemonyTarget> resultTargets) {
        // 先从lastSearchPlayerId开始的后续表中搜索符合条件的目标，找到则返回
        NavigableSet<Integer> tailSet = playerIds.tailSet(lastSearchPlayerId, false);
        for (Integer playerId : tailSet) {
            if (playerId != human.id) { // 不是自己
                // 目标玩家数据一定在内存，否则报错
                Human targetHuman = GameServer.INSTANCE.getHuman(playerId);
                if (targetHuman != null) {
                    // 判断目标是否已被选过，若已选过返回false
                    for (HegemonyTarget target : resultTargets) {
                        if (target.id == playerId) {
                            return false;
                        }
                    }

                    resultTargets.add(new HegemonyTarget(targetHuman));

                    lastSearchPlayerId = playerId;
                    return true;
                } else {
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "Human[" + playerId + "] in PlayerIdsOfRank but not in memory"));
                }
            }
        }

        // 再从头到lastSearchPlayerId为止的前置表中搜索符合条件的目标，找到则返回
        NavigableSet<Integer> headSet = playerIds.headSet(lastSearchPlayerId, false);
        for (Integer playerId : headSet) {
            if (playerId != human.id) { // 不是自己
                // 目标玩家数据一定在内存，否则报错
                Human targetHuman = GameServer.INSTANCE.getHuman(playerId);
                if (targetHuman != null) {
                    // 判断目标是否已被选过，若已选过返回false
                    for (HegemonyTarget target : resultTargets) {
                        if (target.id == playerId) {
                            return false;
                        }
                    }

                    resultTargets.add(new HegemonyTarget(targetHuman));

                    lastSearchPlayerId = playerId;
                    return true;
                } else {
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "Human[" + playerId + "] in PlayerIdsOfRank but not in memory"));
                }
            }
        }

        return false;
    }
}
